// bind使用
#include <iostream>
#include <functional>
using namespace std::placeholders;

#define CC_CALLBACK_0(__selector__, __target__, ...) std::bind(&__selector__, __target__, ##__VA_ARGS__)
#define CC_CALLBACK_1(__selector__, __target__, ...) std::bind(&__selector__, __target__, std::placeholders::_1, ##__VA_ARGS__)
#define CC_CALLBACK_2(__selector__, __target__, ...) std::bind(&__selector__, __target__, std::placeholders::_1, std::placeholders::_2, ##__VA_ARGS__)

class Test
{
private:
  /* data */
public:
  int a = 5;
  Test();
  ~Test();
  void func1(int a)
  {
    std::cout << "a: " << a << std::endl;
  }
  void func2(int a, int b)
  {
    std::cout << "a: " << a << " b: " << b << std::endl;
  }
};

Test::Test(/* args */)
{
}

Test::~Test()
{
}

// 全局函数
void func(int a, int b)
{
  std::cout << "a: " << a << " b: " << b << std::endl;
}

int main(void)
{
  Test t1;
  auto fun1 = std::bind(Test::func1, t1, 2);
  auto fun1_1 = std::bind(Test::func1, t1, _1);
  // auto fun1_2 = std::bind(Test::func1, _2); // static assertion failed: Wrong number of arguments for pointer-to-member
  auto fun1_3 = std::bind(Test::func1, t1, _2);

  // fun1();// 2
  // fun1(3);// 2
  // fun1(3,4,5,6,7);// 2

  // fun1_1(30);// 30
  // fun1_2(10,20);// error
  fun1_3(10,20);// 20

  auto fun2 = [&](int val)
  { t1.func1(val); };
  // fun2(4); // 4

  // 非成员函数 ， 全局函数
  auto func3_1 = std::bind(func, 2, _1);
  auto func3_2 = std::bind(func, _2, _2);
  auto func3_3 = std::bind(func, _3, _4);
  // func3_1(30,40);// 2,30
  // func3_2(30,40);// 40,40
  // func3_3(30,40,50,60);// 50,60

  printf("------------end---------------\n");
  return 0;
}